package com.it.selfAfter.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.selfAfter.entity.Users;
import com.it.selfAfter.dto.RegisterDTO;
import com.it.selfAfter.mapper.UserMapper;
import com.it.selfAfter.service.UserService;
import com.it.selfAfter.utils.Result;
import com.it.selfAfter.utils.UtilUUID;
import com.it.selfAfter.utils.UtilsRandomQuote;
import com.it.selfAfter.utils.UtilsRandomUsername;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, Users> implements UserService{

    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private UserService userService;

//    private final String uploadDir = "./static/images";
    private final String uploadDir = "/deploy/01_selfProject/images";

    /**
     * 注册 新增用户
     * @param registerDTO
     * @return
     */
    @Override
    public Result<?> add(RegisterDTO registerDTO) {
        // 1. 判断该用户两次密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getPassword2())){
            return Result.success("两次输入的密码不匹配");
        }
        // 2. 判断该用户是否已经存在
        Users data = (Users) getUserByPhone(registerDTO.getPhone()).getData();
        if (!ObjectUtils.isEmpty(data)){
            return Result.success("该用户已经存在");
        }
        // 3. 密码相同保存到数据库
        // 创建一个安全的随机数生成器
        SecureRandom random = new SecureRandom();
        // 创建一个包含 20 个字节的随机数字节数组
        byte[] saltBytes = new byte[20];
        // 将随机数组填充到字节数组中
        random.nextBytes(saltBytes);
        // 将字节数组编码为Base64字符串
        String salt = Base64.getEncoder().encodeToString(saltBytes);
        // 计算密码哈希值
        String password = hashPassword(registerDTO.getPassword(), salt);
        // 创建一个新的用户对象
        Users user = new Users(UtilsRandomUsername.generateUsername(),password,null, registerDTO.getPhone(),
              null,salt,new Date(), new Date(),new Date(),new Date(),null,null,null,
              UtilsRandomQuote.getQuote(),UtilsRandomUsername.getInitImg(),registerDTO.getUuid(), registerDTO.getUserId());
        System.out.println(user);
        String username = UtilsRandomUsername.generateUsername();
        String mobile = registerDTO.getPhone();
        String quote = UtilsRandomQuote.getQuote();
        String initImg = UtilsRandomUsername.getInitImg();
        String uuid = registerDTO.getUuid();
        String userId = registerDTO.getUserId();
        int i = userMapper.add(username, password, null, mobile,null, salt, new Date(), new Date(), new Date(), new Date(),
              0, 0, 0, quote, initImg, uuid, userId);
        return i > 0 ? Result.success("注册成功") : Result.failure("注册失败");
    }

    private String hashPassword(String password, String salt) {
        // 将盐和密码组合成一个字符串
        String saltedPassword = salt + password;
        // 创建一个 SHA-256 哈希算法对象
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            // 计算密码哈希值
            byte[] hashBytes = digest.digest(saltedPassword.getBytes(StandardCharsets.UTF_8));
            // 将哈希值编码为 Base64 字符串返回
            return Base64.getEncoder().encodeToString(hashBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据手机号获取用户信息
     * @param phone
     * @return
     */
    public Result<?> getUserByPhone(String phone){
        return Result.success(userMapper.getUsersByPhone(phone));
    }

    /**
     * 用户登录功能
     * @param registerDTO
     * @return
     */
    @Override
    public Result<?> login(RegisterDTO registerDTO) {
        // 根据用户名从数据库中查找用户
        Result<?> userByPhone = getUserByPhone(registerDTO.getPhone());
        Users user = (Users) getUserByPhone(registerDTO.getPhone()).getData();
        if (ObjectUtils.isEmpty(user)){
            // 用户不存在直接返回
            return Result.success(null,"该用户不存在");
        }
        // 计算用户输入的密码的哈希值
        String hashPassword = hashPassword(registerDTO.getPassword(), user.getSalt());
        // 如果哈希值与数据库中的哈希值不相等，则表示密码不正确
        if (!hashPassword.equals(user.getPassword())){
            return Result.success(user,"您输入的密码有误");
        }
        return Result.success(user,"密码正确");
    }

    /**
     * 上传头像
     * @param file
     * @param phone
     * @return
     */
    @Override
    public Result uploadAvatar(MultipartFile file, Long phone) {
        if (file.isEmpty()) {
            return Result.failure("上传失败，文件不能为空");
        }
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        // 根据userId创建目录
        File userDir = new File(uploadDir, String.valueOf(phone));
        if (!userDir.exists()) {
            userDir.mkdirs();
        }
        log.info(userDir.getAbsolutePath(),"------------------------");
        // 保存文件
        // 获取后缀名
        String fileExtension = "";
        int dotIndex = originalFilename.lastIndexOf('.');
        if (dotIndex > 0) {
            fileExtension = "." +  originalFilename.substring(dotIndex + 1);
        }
        String uuid = UtilUUID.getUUID();
        String filePath = userDir.getAbsolutePath() + File.separator + uuid +fileExtension;
        log.info(filePath,"=============================");
        File dest = new File(filePath);
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.failure("上传失败，请重试");
        }
        // 构造头像URL
//        String avatarUrl = "images" + "/"  +  phone + "/" + uuid + fileExtension;
        String avatarUrl = uploadDir + "/"  +  phone + "/" + uuid + fileExtension;
        // 保存到数据库
        int i = userMapper.updateImgByPhone(String.valueOf(phone), avatarUrl);
        if (i >0 ){
            // 返回结果
            Map<String, String> data = new HashMap<>();
            data.put("url", avatarUrl);
            return Result.success(data);
        }
        return Result.failure("上传失败");
    }
    
    
    
    /**
     * 上传图片
     * @param file
     * @param phone
     * @return
     */
    @Override
    public String uploadImg(MultipartFile file, Long phone) {
        if (file.isEmpty()) {
            return null;
        }
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        // 根据userId创建目录
        File userDir = new File(uploadDir, String.valueOf(phone));
        if (!userDir.exists()) {
            userDir.mkdirs();
        }
        log.info(userDir.getAbsolutePath(),"------------------------");
        // 保存文件
        // 获取后缀名
        String fileExtension = "";
        int dotIndex = originalFilename.lastIndexOf('.');
        if (dotIndex > 0) {
            fileExtension = "." +  originalFilename.substring(dotIndex + 1);
        }
        String uuid = UtilUUID.getUUID();
        String filePath = userDir.getAbsolutePath() + File.separator + uuid +fileExtension;
        log.info(filePath,"=============================");
        File dest = new File(filePath);
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        // 构造头像URL
//        String imgKey = "images" + "/"  +  phone + "/" + uuid + fileExtension;
        String imgKey = uploadDir + "/"  +  phone + "/" + uuid + fileExtension;
        // 返回结果
       return imgKey;
    }
    
    
    
    /**
     * 更新今日名言
     * @param phone
     * @param quote
     * @return
     */
    @Override
    public Result<?> updateQuote(String phone, String quote) {
        int i = userMapper.updateQuote(phone, quote);
        if (i>0){
            return Result.success(userMapper.getUsersByPhone(phone));
        }
        return Result.failure("更新失败！");
    }

    @Override
    public Result<?> getUsersByUserId(String userId) {

        Users user = userMapper.getUsersByUserId(userId);
        log.info("======================={}=============",user);
        if (ObjectUtils.isEmpty(user)){
            // 用户不存在直接返回
            return Result.success("该用户不存在");
        }
        return Result.success(user);
    }

    @Override
    public Result<?> updateUUIDByPhone(String phone, String uuid) {
        int i = userMapper.updateUUIDByPhone(phone, uuid);
        if (i>0){
            return Result.success(userMapper.getUsersByPhone(phone));
        }
        return Result.failure("更新失败！");
    }
}
